# -*- coding: utf-8 -*-
# @Time    : 2024/09/27 14:54
# @Author  : Alvin
# @File    : BaseLogisticsImpl.py
# @Des     : 车满满物流更新基类
import hashlib
import json
import logging
import logging.handlers
import os
import time
import traceback
from datetime import datetime
import random

import requests

from constants import Constants
from utils import CommonUtil, CheUtil
from utils.DatabaseHandler import DatabaseHandler


class BaseLogisticsImpl:
    def __init__(self):
        self.PHPSESSID = ""
        self.query_express_code_url = "https://www.kuaidi100.com/autonumber/auto"
        self.query_logistics_info_url = "https://poll.kuaidi100.com/poll/query.do"
        self.query_express_code_url = "https://www.kuaidi100.com/autonumber/auto"
        self.query_logistics_info_url = "https://poll.kuaidi100.com/poll/query.do"
        self.db_util = DatabaseHandler()
        self.lanShouList = ['1', '101', '102', '103']
        self.yunShuZhong = ['0', '1001', '1002', '1003']
        self.qianShouList = ['3', '301', '302', '303', '304', '4', '401', '14']
        self.typeList = ['已发车', '中转中']
        self.TYPE_YIFACHE = "已发车"
        self.TYPE_ZHONGZHUANZHONG = "中转中"
        self.TYPE_SB_PS = "三包派送"
        self.TYPE_TIHUO_JUJUE = "提货已拒绝"
        self.app_token = '374f727d-ff2d-4cb1-b168-7321c8f3109d'
        current_path = os.path.dirname(__file__)
        project_root = os.path.abspath(os.path.join(current_path, '../../..'))
        self.defaultFile = f"{project_root}/token.json"
        if os.path.exists(self.defaultFile):
            with open(self.defaultFile, mode='r', encoding='utf-8') as file:
                content = file.read()
                content_dict = json.loads(content)
                self.token = content_dict.get("token")
                self.requestToken = content_dict.get("requestToken")
        else:
            isSuccess = self.do_lan_qiao_login()
            if not isSuccess:
                raise Exception("单号更新前置步骤异常，请联系管理员")
            print("登录", isSuccess)

    def check_user_is_logined(self):
        """
        判断用户是否已经登录，如果掉线则调用登录接口，如果没有掉线则继续实现业务
        :return:
        """
        try:
            headers = CheUtil.get_request_header(self.token, self.requestToken)
            url = "https://apit9.lqfast.com/lanqiao-tms-app/web/common/getSkinData"
            u = CheUtil.get_param_u(self.token)
            data = {
                "m": "func",
                "n": "getSkinData",
                "p": {},
                "l": "",
                "v": "",
                "u": u,
                "r": "k",
                "s": "k",
                "t": CommonUtil.get_current_timetamp()
            }
            resp_json = requests.post(url, headers=headers, json=data).json()
            logging.info(f"检查登录状态响应：{resp_json}")
            is_online = resp_json.get("success")
            if not is_online:
                isLoginSuccess = self.do_lan_qiao_login()
                if not isLoginSuccess:
                    return False
            return True
        except Exception as ex:
            logging.error(f"检查系统登录方法出现异常，异常内容：{str(ex)}")
            logging.error("检查系统登录方法出现异常:%s", traceback.format_exc())

    def do_lan_qiao_login(self):
        """
        车氏物流账号密码登录，此处登录使用的是固定账号密码
        :return:
        """
        try:
            headers = {
                "accept": "*/*",
                "accept-language": "zh-CN,zh;q=0.9",
                "cache-control": "no-cache",
                "content-type": "application/json; charset=UTF-8",
                "hango-origin": "lanqiao",
                "origin": "https://www.561861.cn",
                "pragma": "no-cache",
                "priority": "u=1, i",
                "referer": "https://www.561861.cn/",
                "sec-ch-ua": "\"Chromium\";v=\"136\", \"Google Chrome\";v=\"136\", \"Not.A/Brand\";v=\"99\"",
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "\"Windows\"",
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "cross-site",
                "tenantcode": "78210",
                "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36"
            }
            url = "https://apit9.lqfast.com/lanqiao-tms-app/web/account/loginVerify"
            user_name = Constants.user_name
            pwd = CommonUtil.get_encrypt_pwd(Constants.password)
            data = {
                "m": "func",
                "n": "loginVerify",
                "p": {
                    "webtoken": pwd,
                    "tmscode": "78210",
                    "loginname": user_name,
                    "pwd": pwd,
                    "officialwebsite": 1,
                    "verifycode": "",
                    "userid": "优斯雅通达",
                    "Password": pwd,
                    "storeProcedure": "QSP_GET_BASEINFO"
                },
                "l": "",
                "v": "",
                "u": {
                    "tmsCode": "78210",
                    "userId": user_name,
                    "tmsbshxsite": "",
                    "browserId": None
                },
                "r": "k",
                "s": "k",
                "t": CommonUtil.get_current_timetamp()
            }
            resp_json = requests.post(url, headers=headers, json=data).json()
            is_logistics_success = resp_json.get("success")
            if is_logistics_success:
                login_data = resp_json.get("data")
                login_key = login_data.get("key")
                return self.get_user_info(login_key)
            return False
        except Exception as ex:
            logging.error(f"do_lan_qiao_login 异常：{str(ex)}")
            logging.error("do_lan_qiao_login 异常:%s", traceback.format_exc())
            return False

    def get_user_info(self, logistics_key):
        try:
            headers = {
                "accept": "*/*",
                "accept-language": "zh-CN,zh;q=0.9",
                "cache-control": "no-cache",
                "content-type": "application/json; charset=UTF-8",
                "hango-origin": "lanqiao",
                "origin": "https://t9bs.lqfast.com",
                "pragma": "no-cache",
                "priority": "u=1, i",
                "referer": "https://t9bs.lqfast.com/",
                "requesttoken": "0A70ABB1C58F4DE290D67BEFAB9A92F6",
                "sec-ch-ua": "\"Chromium\";v=\"136\", \"Google Chrome\";v=\"136\", \"Not.A/Brand\";v=\"99\"",
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "\"Windows\"",
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-site",
                "tenantcode": "78210",
                "token;": "",
                "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36"
            }
            url = "https://apit9.lqfast.com/lanqiao-tms-app/web/account/loginGetUserInfo"
            data = {
                "m": "func",
                "n": "loginGetUserInfo",
                "p": {
                    "key": logistics_key
                },
                "l": "",
                "v": "",
                "u": {},
                "r": "k",
                "s": "k",
                "t": CommonUtil.get_current_timetamp()
            }
            resp_json = requests.post(url, headers=headers, json=data).json()
            status = resp_json.get("success")
            if not status:
                return False
            user_info = resp_json.get("data")
            self.token = user_info.get("token")
            self.requestToken = user_info.get("requestToken")

            write_data = {
                "token": user_info.get("token"),
                "requestToken": user_info.get("requestToken"),
            }
            with open(self.defaultFile, mode='w', encoding='utf-8') as file:
                file.write(json.dumps(write_data))
            return True
        except Exception as ex:
            logging.error(f"get_user_info 异常：{str(ex)}")
            logging.error("get_user_info 异常:%s", traceback.format_exc())
            return False

    # 调用快递100接口识别快递公司编号
    def query_express_code(self, expressNum):
        try:
            if not expressNum:
                return None
            req_params = {'key': Constants.BaseContent.kuaidi100Key, 'num': expressNum}
            rawResponse = requests.post(self.query_express_code_url, req_params)
            query_resp = rawResponse.json()
            if type(query_resp) == list and len(query_resp) > 0:
                resp_item = query_resp[0]
                comCode = resp_item.get('comCode')
                name = resp_item.get('name')
                return comCode, name
            else:
                return None, None
        except Exception as ex:
            logging.error(f"query_express_code error:{str(expressNum)}，{str(ex)}")
            return None, None

    def queryLogisticsInfoByKuaiDi100(self, mailNo, companyCode):
        """
        从快递100查询物流信息
        :param mailNo:
        :param companyCode:
        :return:
        """
        param = {
            'com': companyCode,
            'num': mailNo,
            'phone': '',
            'from': None,
            'to': None,
            'resultv2': 4,  # 添加此字段表示开通行政区域解析功能。0：关闭（默认），1：开通行政区域解析功能，2：开通行政解析功能并且返回出发、目的及当前城市信息
            'show': '0',  # 返回数据格式。0：json（默认），1：xml，2：html，3：text
            'order': 'desc'  # 返回结果排序方式。desc：降序（默认），asc：升序
        }
        param_str = json.dumps(param)
        temp_sign = param_str + Constants.BaseContent.kuaidi100Key + Constants.BaseContent.kuaidi100Customer
        md = hashlib.md5()
        md.update(temp_sign.encode())
        sign = md.hexdigest().upper()
        request_data = {'customer': Constants.BaseContent.kuaidi100Customer, 'param': param_str, 'sign': sign}
        response = requests.post(self.query_logistics_info_url, request_data)
        resp_data = response.json()
        if "status" in resp_data and resp_data['status'] == '200' and resp_data['message'] == 'ok':
            # logging.info(f"【{mailNo}】快递100接口返回:{response.text}")
            return resp_data
        else:
            logging.info(f"快递100返回异常:{resp_data},参数-->{param}")
            return None

    # 获取上一次更新的物流时间在物流轨迹列表中的位置
    def getLastUpdateTimeIndex(self, lastUpdateTime, logisticsList):
        """
            获取上一次更新的时间在物流轨迹列表中的角标
        """
        try:
            lastUpdateTimeIndex = -1
            for index, item in enumerate(logisticsList):
                if lastUpdateTime == item['time']:
                    lastUpdateTimeIndex = index
                    break
            return lastUpdateTimeIndex
        except Exception as ex:
            logging.error(f"获取上一次更新时间异常：{str(ex)}")
            return -1

    def get_order_detail(self, mailNo_self):
        """
        获取订单详情
        :param mailNo_self:
        :return:
        """
        headers = CheUtil.get_request_header(self.token, self.requestToken)
        url = "https://apit9.lqfast.com/lanqiao-tms-app/web/publicData/getUnitDateil"
        data = {
            "m": "func",
            "n": "getUnitDateil",
            "p": {
                "unit": mailNo_self
            },
            "l": "",
            "v": "",
            "u": CheUtil.get_param_u(self.token),
            "r": "k",
            "s": "k",
            "t": int(time.time() * 1000)
        }
        data = json.dumps(data, separators=(',', ':'))
        resp_json = requests.post(url, headers=headers, data=data).json()
        status = resp_json.get("success")
        if not status:
            logging.error(f"[{mailNo_self}] 获取订单详情失败，接口响应：{resp_json}")
            return None
        order_detail_data_list = resp_json.get("data")
        return order_detail_data_list[0]
